package entities;

import com.haxepunk.Entity;
import com.haxepunk.graphics.Image;
import com.haxepunk.graphics.Spritemap;
import com.haxepunk.Mask;
import com.haxepunk.masks.Pixelmask;
import com.haxepunk.tmx.TmxObject;
import com.haxepunk.HXP;
import com.haxepunk.utils.Input;
import com.haxepunk.utils.Key;
import flash.geom.Point;
import entities.*;
import hxcollision.Collision;
import hxcollision.CollisionData;
import hxcollision.shapes.Polygon;
import hxcollision.shapes.Shape;
import hxcollision.math.Vector;
import src.entities.Mensaje;


enum StateProtobot
{
	IDLE; WALK; JUMP;
}

/**
 * ...
 * @author Marcelo Ruben Guardia
 */
class Protobot extends Entity
{
	//private var spProtobot:Spritemap;
	private var imgProtobot:Image;
	private var v:Point;
	private var state:StateProtobot;
	private var speedX:Float;
	private var speedW:Float;
	//private var shape:Shape;
	private var polygon:Polygon;
	private var collideInfo:CollisionData;
	
	// variables para los accesorios que recolecta el robot
	// de las piernas
	private var legs:LegsRobot;
	// del arma
	private var conGun:Bool;
	private var gun:Gun;
	// del magneto
	private var conMagnet:Bool;
	private var magnet:Magnet;
	
	public function new(obj:TmxObject) 
	{
		super(obj.x, obj.y);
		
		imgProtobot = new Image(GC.IMG_protobot);
		imgProtobot.scale = 0.5;
		imgProtobot.centerOrigin();
		setHitbox(64, 64, 32, 32);
		//shape = new Polygon(32, 32, Vector(64, 64));
		polygon = Polygon.rectangle(32, 32, 64, 64);
		
		
		graphic = imgProtobot;
		//mask = new Pixelmask(GC.IMG_protobot_mask, -32, -32);
		
		type = "protobot";
		
		Input.define("move_left", [Key.A, Key.LEFT]);
		Input.define("move_right", [Key.D, Key.RIGHT]);
		Input.define("move_up", [Key.W, Key.UP]);
		Input.define("move_down", [Key.S, Key.DOWN]);
		Input.define("trigger_magnet", [Key.T]);
		
		v = new Point();
		state = IDLE;
		speedX = 4;
		speedW = 5;
		
		// de las piernas
		legs = null;
		// del arma
		conGun = false;
		gun = null;
		// del magneto
		conMagnet = false;
		magnet = null;
		
	}
	
	override public function update():Void
	{
		HXP.setCamera(x - HXP.screen.width / 2, y - HXP.screen.height / 2);
		
		moveBy(v.x, v.y, "solid");

		polygon.x = x;
		polygon.y = y;

		switch(state)
		{
			case IDLE:
				if (MoveRight() || MoveLeft())
				{
					state = WALK;
				}
				
				if (!ChocaraPiso())
				{
					state = JUMP;
				}
				
			case WALK:
				MoveRight() ? v.x = speedX : v.x = -speedX;
				MoveRight() ? imgProtobot.angle-= speedW : imgProtobot.angle += speedW;
				if (!MoveLeft() && !MoveRight())
				{
					state = IDLE;
					v.x = 0;
				}
				
				if (!ChocaraPiso())
				{
					state = JUMP;
				}
				
			case JUMP:
				v.y += GC.G * HXP.elapsed;
				if (ChocaraPiso())// || collide("platform", x, y + 1)!=null)//)
				{
					state = IDLE;
					v.y = 0;
					v.x = 0;
					//trace("piso");
				}
				/*
				if (ChocaraPlataforma(x, y + 1))
				{
					state = IDLE;
					v.y = 0;
					v.x = 0;
					var platform:MetalPlatform;
					if ((platform = cast(collide("platform", x, y), MetalPlatform)) != null)
					{
						var polygon2 = platform.GetPolygon();
						collideInfo = Collision.test(polygon, polygon2);
						if (collideInfo != null)
						{
							collideInfo.separation.y;
						}
					}
				}
				*/
				
				if (ChocaraTecho())// || ChocaraPlataforma(x, y))
				{
					v.y = 1;
					/*
					var platform:MetalPlatform;
					if ((platform = cast(collide("platform", x, y), MetalPlatform)) != null)
					{
						var polygon2 = platform.GetPolygon();
						collideInfo = Collision.test(polygon, polygon2);
						if (collideInfo != null)
						{
							collideInfo.separation.y;
						}
					}
					*/
					//trace("asdf");
				}
				
				if (ChocaraPared())// || collide("platform", x + ((v.x > 0)?1: -1), y)!=null)//ChocaraParedPlataforma())
				{
					v.x = 0;
					/*
					var platform:MetalPlatform;
					if ((platform = cast(collide("platform", x, y), MetalPlatform)) != null)
					{
						var polygon2 = platform.GetPolygon();
						collideInfo = Collision.test(polygon, polygon2);
						if (collideInfo != null)
						{
							collideInfo.separation.x;
						}
					}
					*/
					//trace("asdf2");
				}
				
				
		}		
		
		DoLegs();
		DoGun();
		DoMagnet();
		super.update();
		//trace(state.getName());
	}
	
	public function GetPolygon():Polygon
	{
		return polygon;
	}
	
	public function DoLegs():Void
 {
		if (legs == null)
		{
			if ((legs = cast(collide("legs_robot", x, y), LegsRobot)) != null)
			{
				legs.SetProtobot(this);
				scene.add(new Mensaje(
				"Utilice las piernas del robot\n"
				+"para saltar obstaculos.\n"
				+"Se utiliza con la tecla SPACE", new Point(x - 125, y - 140), 20));
			}
		}
		else
			legs.update();		
	}
	
	public function DoGun():Void
	{
		if (!conGun)
		{
			if ((gun = cast(collide("gun", x, y), Gun)) != null)
			{
				conGun = true;
				scene.add(new Mensaje(
				"Utilice el arma laser para\n"
				+"dispararle a sus enemigos y\n"
				+"algunos objetos destructibles.\n"
				+"Se utiliza con el Botón\n Izquierdo del Mouse.", new Point(x - 80, y + 90), 20));
			}
		}
		else
		{
			gun.x = x;
			gun.y = y;
			ActionGun();
		}
	}
	
	public function ActionGun():Void
	{
		gun.SetAngle(HXP.angle(x, y, Input.mouseX + HXP.camera.x, Input.mouseY + HXP.camera.y) + 90);
		if (Input.mousePressed)
		{
			gun.Shoot();
		}
	}

	public function DoMagnet():Void
	{
		if (!conMagnet)
		{
			if ((magnet = cast(collide("magnet", x, y), Magnet)) != null )
			{
				conMagnet = true;
				scene.add(new Mensaje(
				"Utilice el magneto para elevarse cuando\n"
				+"esté debajo de las plataformas con amarillo y negro\n"
				+"Se activa/desactiva con la tecla T.\n"
				+"Se utiliza con la tecla W ó Flecha Arriba.", new Point(x - 125, y - 140), 20));
			}
		}
		else
		{
			magnet.x = x;
			magnet.y = y;
			ActionMagnet();
		}
	}
	
	public function ActionMagnet():Void
	{
		if (TriggerMagnet())
		{
			magnet.ChangeMagnet();
		}
		
		if (magnet.GetState() == Magnet.StateMagnet.ACTIVE && MoveUp())
		{
			var auxX = Math.floor(get_centerX());
			var auxY = Math.floor(get_centerY());
			var platform:MetalPlatform = cast(scene.collideLine("solid", auxX, auxY, auxX, auxY - 150), MetalPlatform);
			if (platform != null)
			{
				if (magnet.collideWith(platform,x,y) == null)
				{
					v.y = v.y - 0.5;
				}
				else
				{
					v.y = 0;
				}
			}
		}
		
		if (magnet.collide("platform", x, y) != null)
		{
			v.y = 0;
		}
	}
	
	public function FollowPlatform():Void
	{
		
	}
	
	public function ChocaraPiso():Bool	
	{
		return (collide("solid", x, y + 1) != null);
	}
	
	public function ChocaraTecho():Bool	{		return (collide("solid", x, y - 1) != null);	}
	
	public function ChocaraPlataforma(valorX:Float, valorY:Float):Bool 
	{
		return (collide("platform", valorX, valorY) != null);	
	}
	
	public function ChocaraContra(type:String, valorX:Float, valorY:Float):Bool
 {
		return (collide(type.toString(), valorX, valorY) != null);
	}
	
	public function ChocaraPared():Bool {  return (collide("solid", x + ((v.x > 0)?1: -1), y) != null);	}
	public function ChocaraParedPlataforma():Bool {  return (collide("platform", x + ((v.x > 0)?1: -1), y) != null);	}
	
	public function MoveLeft():Bool		{		return Input.check("move_left");	}
	public function MoveRight():Bool	{	 return Input.check("move_right");}
	public function MoveUp():Bool				{	 return Input.check("move_up");	  }
	public function MoveDown():Bool		{		return Input.check("move_down");	}
	public function TriggerMagnet():Bool { return Input.check("trigger_magnet");	}
	
	public function SetVelocity(vx:Float, vy:Float):Void
	{
		v = new Point(vx, vy);
	}
	
	public function GetVelocity():Point
	{
		return v;
	}
	
	public function GetState():StateProtobot
	{
		return state;
	}
	
	public function ChangeState(newState:StateProtobot):Void
	{
		state = newState;
	}
}